package com.cxs.controller;

import com.cxs.dto.*;
import com.cxs.enums.HospitalErrorResultEnum;
import com.cxs.exception.HospitalException;
import com.cxs.pojo.*;
import com.cxs.service.*;
import com.cxs.vo.*;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List;

/*
 * @Author:cxs
 * @Date:2021/10/20  14:30
 * @Version 1.0
 * @Motto:放下杂念,只为迎接明天更好的自己
 * 门诊处理器
 * */
@Slf4j
@RestController
@RequestMapping("/cao")
public class CaoController {
    @Autowired
    private DepartmentSevice departmentSevice;

    @Autowired
    private RegisteredTypeService registeredTypeService;

    @Autowired
    private ReportService reportService;

    @Autowired
    private DocterService docterService;

    @Autowired
    private CashierService cashierService;

    @Autowired
    private PharmacyService pharmacyService;

    @Autowired
    private OutPatientTypeService outPatientTypeService;

    /**
     * 挂号信息处理器方法
     *
     * @param cc
     * @param name
     * @return
     */
    @GetMapping("/index")
    public Result index(String cc, String name) {
        return Result.Ok(reportService.getList(cc, name));
    }

    /**
     * 科室处理器方法
     *
     * @return
     */
    @GetMapping("/seldep")
    public Result seldep() {
        return Result.Ok(departmentSevice.findDepts());
    }

    /**
     * 挂号类型处理器方法
     *
     * @return
     */
    @GetMapping("/selreg")
    public Result selreg() {
        return Result.Ok(registeredTypeService.findregTypes());
    }

    /**
     * 医生列表处理器方法
     *
     * @param registeredId
     * @param departmentId
     * @return
     */
    @PostMapping("/seldoctor")
    public Result seldoctor(Integer registeredId, Integer departmentId) {
        return Result.Ok(docterService.getList(registeredId, departmentId));
    }

    /**
     * 查询挂号费用
     *
     * @param registeredId
     * @return
     */
    @PostMapping("/selRegMoney")
    public Result selRegMoney(Integer registeredId) {
        if (StringUtils.isEmpty(registeredId)) {
            log.info("【挂号模块】:挂号类型id不能为空,registeredId = {}", registeredId);
            throw new HospitalException(HospitalErrorResultEnum.REQUEST_PARAMETERS_ERROR.getCode(), "registeredId必传项");
        }
        return Result.Ok(registeredTypeService.getMoney(registeredId));
    }

    /**
     * 查看手机号、身份证是否存在
     *
     * @param carid
     * @return
     */
    @PostMapping("/phone")
    public Result phone(String carid, String phone) {
        if (StringUtils.isEmpty(carid) || StringUtils.isEmpty(phone)) {
            log.info("【挂号模块】:carid、phone不能为空,carid = {},phone = {}", carid, phone);
            throw new HospitalException(HospitalErrorResultEnum.REQUEST_PARAMETERS_ERROR.getCode(), "carid、phone必传项");
        }
        return Result.Ok(reportService.checkPhoneAndCid(phone, carid));
    }


    /**
     * 添加一位门诊信息
     *
     * @param reportDTO
     * @param bindingResult
     * @return
     */
    @PostMapping("/addReport")
    public Result addReport(@Valid ReportDTO reportDTO, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            log.info(bindingResult.getFieldError().getDefaultMessage());
            throw new HospitalException(HospitalErrorResultEnum.REQUEST_PARAMETERS_ERROR.getCode(), bindingResult.getFieldError().getDefaultMessage());
        }

        User user = getUser();

        if (user == null) {
            throw new HospitalException(HospitalErrorResultEnum.NO_LOGIN_ERROR);
        }

        reportDTO.setUsers(user.getRealName());

        reportService.addReport(reportDTO);

        return Result.Ok();
    }

    /**
     * 逻辑删除一位病人
     *
     * @param id
     * @return
     */
    @PostMapping("/delre")
    public Result delre(Integer id) {
        if (StringUtils.isEmpty(id)) {
            log.info("【门诊删除】:病人id不能为空");
            throw new HospitalException(HospitalErrorResultEnum.REQUEST_PARAMETERS_ERROR.getCode(), "病人id为必传项");
        }

        reportService.del(id);

        return Result.Ok();
    }

    /**
     * 查询该用户处方上是否有药品
     *
     * @param reportId
     * @return
     */
    @PostMapping("/selch")
    public Result selch(Integer reportId) {
        if (StringUtils.isEmpty(reportId)) {
            log.info("【门诊入院】:病人id不能为空");
            throw new HospitalException(HospitalErrorResultEnum.REQUEST_PARAMETERS_ERROR.getCode(), "病人id为必传项");
        }
        return cashierService.checkHasNoCh(reportId);
    }

    /**
     * 查询该用户处方上是否有未交费项目
     *
     * @param reportId
     * @return
     */
    @PostMapping("/seljiao")
    public Result seljiao(Integer reportId) {
        if (StringUtils.isEmpty(reportId)) {
            log.info("【门诊入院】:病人id不能为空");
            throw new HospitalException(HospitalErrorResultEnum.REQUEST_PARAMETERS_ERROR.getCode(), "病人id为必传项");
        }
        return cashierService.checkHasNoPro(reportId);
    }

    /**
     处方划价开始
     */

    /**
     * 查询当天病人
     *
     * @param name
     * @param pageNo
     * @param limit
     * @return
     */
    @GetMapping("/tselpreson")
    public Result tselpreson(String name,
                             @RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
                             @RequestParam(value = "limit", defaultValue = "5") Integer limit) {

        PageInfo<Report> pageInfo = reportService.getPageInfo(name, pageNo, limit);

        List<Report> list = pageInfo.getList();

        List<ReportIndexVO> voList = new ArrayList<>();

        for (Report report : list) {
            ReportIndexVO vo = new ReportIndexVO();
            BeanUtils.copyProperties(report, vo);
            voList.add(vo);
        }

        Result result = new Result();
        result.put("count", pageInfo.getTotal());
        result.put("code", 0);
        result.put("msg", "");
        result.put("data", voList);
        return result;
    }

    /**
     * 查询库存药品
     *
     * @param durgname
     * @param pageNo
     * @param limit
     * @return
     */
    @GetMapping("/seldrug")
    public Result seldrug(String durgname,
                          @RequestParam(value = "page", defaultValue = "1") Integer pageNo,
                          @RequestParam(value = "limit", defaultValue = "5") Integer limit) {
        PageInfo<Pharmacy> pageInfo = pharmacyService.selDrug(durgname, pageNo, limit);

        List<PharmacySimVO> list = new ArrayList<>();

        for (Pharmacy p : pageInfo.getList()) {
            PharmacySimVO vo = new PharmacySimVO();
            BeanUtils.copyProperties(p, vo);
            list.add(vo);
        }
        Result result = new Result();
        result.put("count", pageInfo.getTotal());
        result.put("code", 0);
        result.put("msg", "");
        result.put("data", list);
        return result;
    }

    /**
     * 查询患者开过的所有药
     *
     * @return
     */
    @GetMapping("/selAll")
    public Result selAll(Integer reportId,
                         @RequestParam(value = "page", defaultValue = "1") Integer pageNo,
                         @RequestParam(value = "limit", defaultValue = "5") Integer limit) {
        if (StringUtils.isEmpty(reportId)) {
            log.error("【处方划价】: 病人id为必传项,reportId = {}", reportId);
            throw new HospitalException(HospitalErrorResultEnum.REQUEST_PARAMETERS_ERROR.getCode(), "病人reportId为必传项");
        }

        PageInfo<Cashier> pageInfo = cashierService.selAllByReportIdPage(reportId, pageNo, limit);

        List<CashierSimVo> list = new ArrayList<>();

        for (Cashier c : pageInfo.getList()) {
            CashierSimVo vo = new CashierSimVo();
            BeanUtils.copyProperties(c, vo);
            list.add(vo);
        }
        Result result = new Result();
        result.put("count", pageInfo.getTotal());
        result.put("code", 0);
        result.put("msg", "");
        result.put("data", list);
        return result;
    }

    /**
     * 查询病人病因
     *
     * @param reportId
     * @return
     */
    @PostMapping("/selbing")
    public Result selbing(Integer reportId) {
        if (StringUtils.isEmpty(reportId)) {
            log.error("【处方划价】: 病人id为必传项,reportId = {}", reportId);
            throw new HospitalException(HospitalErrorResultEnum.REQUEST_PARAMETERS_ERROR.getCode(), "病人reportId为必传项");
        }

        Report report = reportService.getBing(reportId);

        return Result.Ok(report);
    }

    /**
     * 添加病因
     *
     * @param reportId
     * @param bing
     * @return
     */
    @PostMapping("/addbing")
    public Result addbing(Integer reportId, String bing) {
        if (StringUtils.isEmpty(reportId)) {
            log.error("【处方划价】: 病人id为必传项,reportId = {}", reportId);
            throw new HospitalException(HospitalErrorResultEnum.REQUEST_PARAMETERS_ERROR.getCode(), "病人reportId为必传项");
        }

        if (StringUtils.isEmpty(bing)) {
            log.error("【处方划价】: 病人病因为必传项,bing = {}", bing);
            throw new HospitalException(HospitalErrorResultEnum.REQUEST_PARAMETERS_ERROR.getCode(), "病人病因为必传项");
        }
        // 封装信息
        Report report = new Report();
        report.setReportId(reportId);
        report.setZhuan(bing.trim());

        reportService.update(report);

        return Result.Ok();
    }

    /**
     * 查询病人此药品是否开过
     * @param reportId
     * @param mename
     * @return
     */
    @PostMapping("/selchu")
    public Result selchu(Integer reportId, String mename){
        if (StringUtils.isEmpty(reportId)) {
            log.error("【处方划价】: 病人id为必传项,reportId = {}", reportId);
            throw new HospitalException(HospitalErrorResultEnum.REQUEST_PARAMETERS_ERROR.getCode(), "病人reportId为必传项");
        }

        if (StringUtils.isEmpty(mename)) {
            log.error("【处方划价】: 药品名为必传项,bing = {}", mename);
            throw new HospitalException(HospitalErrorResultEnum.REQUEST_PARAMETERS_ERROR.getCode(), "药品名为必传项");
        }

        return cashierService.checkDrupExist(reportId,mename);
    }

    /**
     * 给病人药品
     * @param cashierDTO
     * @param bindingResult
     * @return
     */
    @PostMapping("/addchu")
    public Result addchu(@Valid AddCashierDTO cashierDTO,BindingResult bindingResult){
        if (bindingResult.hasErrors()) {
            log.info(bindingResult.getFieldError().getDefaultMessage());
            throw new HospitalException(HospitalErrorResultEnum.REQUEST_PARAMETERS_ERROR.getCode(), bindingResult.getFieldError().getDefaultMessage());
        }

        Cashier c = new Cashier();
        BeanUtils.copyProperties(cashierDTO,c);

        cashierService.add(c);

        return Result.Ok();
    }

    /**
     * 修改处方信息，开药是已经有
     * @param cashierDTO
     * @param bindingResult
     * @return
     */
    @PostMapping("/updchu")
    public Result updchu(@Valid UpdateCashierDTO cashierDTO, BindingResult bindingResult){
        if (bindingResult.hasErrors()) {
            log.info(bindingResult.getFieldError().getDefaultMessage());
            throw new HospitalException(HospitalErrorResultEnum.REQUEST_PARAMETERS_ERROR.getCode(), bindingResult.getFieldError().getDefaultMessage());
        }

        Cashier c = new Cashier();
        BeanUtils.copyProperties(cashierDTO,c);

        cashierService.update(c);

        return Result.Ok();
    }

    /**
     * 删除开过为付款的药品
     * @param id
     * @return
     */
    @PostMapping("/del")
    public Result del(Integer id){
        if (StringUtils.isEmpty(id)) {
            log.error("【处方划价】: 药品id为必传项,id = {}", id);
            throw new HospitalException(HospitalErrorResultEnum.REQUEST_PARAMETERS_ERROR.getCode(), "药品id为必传项");
        }

        cashierService.del(id);

        return Result.Ok();
    }
    /*
      项目划价
     */

    /**
     * 条件查询项目
     * @param projectName
     * @return
     */
    @GetMapping("/selout")
    public Result selout(String projectName,
                         @RequestParam(value = "page", defaultValue = "1") Integer pageNo,
                         @RequestParam(value = "limit", defaultValue = "5") Integer pageSize){

        PageInfo<OutPatientType> pageInfo = outPatientTypeService.patientInfoPage(projectName, pageNo, pageSize);
        List<OutPatientTypeVO> list = new ArrayList<>();

        for (OutPatientType o : pageInfo.getList()) {
            OutPatientTypeVO vo = new OutPatientTypeVO();
            BeanUtils.copyProperties(o, vo);
            list.add(vo);
        }
        Result result = new Result();
        result.put("count", pageInfo.getTotal());
        result.put("code", 0);
        result.put("msg", "");
        result.put("data", list);
        return result;
    }

    /**
     * 查询病人的项目
     * @param perid
     * @param pageNo
     * @param pageSize
     * @return
     */
    @GetMapping("/selximu")
    public Result selximu(Integer perid,
                         @RequestParam(value = "page", defaultValue = "1") Integer pageNo,
                         @RequestParam(value = "limit", defaultValue = "5") Integer pageSize){

        if (StringUtils.isEmpty(perid)) {
            log.error("项目划价】: 病人id为必传项,reportId = {}", perid);
            throw new HospitalException(HospitalErrorResultEnum.REQUEST_PARAMETERS_ERROR.getCode(), "病人perid为必传项");
        }

        PageInfo<Cashier> pageInfo = cashierService.selAllByOutReportIdPage(perid,pageNo,pageSize);
        List<CashierSimVo> list = new ArrayList<>();

        for (Cashier o : pageInfo.getList()) {
            CashierSimVo vo = new CashierSimVo();
            BeanUtils.copyProperties(o, vo);
            list.add(vo);
        }
        Result result = new Result();
        result.put("count", pageInfo.getTotal());
        result.put("code", 0);
        result.put("msg", "");
        result.put("data", list);
        return result;
    }

    @PostMapping("/delo")
    public Result delo(Integer cashierId){
        if (StringUtils.isEmpty(cashierId)) {
            log.error("项目划价】: 项目id为必传项,cashierId = {}", cashierId);
            throw new HospitalException(HospitalErrorResultEnum.REQUEST_PARAMETERS_ERROR.getCode(), "cashierId为必传项");
        }

        cashierService.delete(cashierId);

        return Result.Ok();
    }

    /**
     * 检查是否开过
     * @param reportId
     * @param durgName
     * @return
     */
    @PostMapping("/checkpro")
    public Result checkpro(Integer reportId,String durgName){
        if(StringUtils.isEmpty(reportId)){
            log.error("项目划价】: 病人id为必传项,reportId = {}", reportId);
            throw new HospitalException(HospitalErrorResultEnum.REQUEST_PARAMETERS_ERROR.getCode(), "病人id为必传项");
        }

        if(StringUtils.isEmpty(durgName)){
            log.error("项目划价】: 项目名为必传项,durgName = {}", durgName);
            throw new HospitalException(HospitalErrorResultEnum.REQUEST_PARAMETERS_ERROR.getCode(), "项目名为必传项");
        }

        return cashierService.checkProExist(reportId, durgName);
    }

    /**
     * 添加项目
     * @param cashierProDTO
     * @param bindingResult
     * @return
     */
    @PostMapping("/addchuo")
    public Result addchuo(@Valid AddCashierProDTO cashierProDTO,BindingResult bindingResult){
        if (bindingResult.hasErrors()) {
            log.info(bindingResult.getFieldError().getDefaultMessage());
            throw new HospitalException(HospitalErrorResultEnum.REQUEST_PARAMETERS_ERROR.getCode(), bindingResult.getFieldError().getDefaultMessage());
        }

        cashierService.addPro(cashierProDTO);

        return Result.Ok();
    }

    private User getUser() {
        Subject subject = SecurityUtils.getSubject();

        Object principal = subject.getPrincipal();

        if (principal != null) {
            return (User) principal;
        }
        return null;
    }
}
